package com.cskaoyan.service;


import com.cskaoyan.bean.bo.*;
import com.cskaoyan.bean.data.BaseData;
import com.cskaoyan.bean.pojo.*;
import com.cskaoyan.bean.pojo.System;
import com.cskaoyan.bean.pojo.admin.AdminExample;
import com.cskaoyan.bean.vo.*;
import com.cskaoyan.converter.SystemConverter;
import com.cskaoyan.dao.*;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author thz
 * @class SystemServiceImpl
 */

@Service
@PropertySource("classpath:host.properties")
public class SystemServiceImpl implements SystemService {

    @Value("${host.domain}")
    private String host;

    @Autowired
    AdminMapperUsedByTHZ adminMapper;

    @Autowired
    RoleMapper roleMapper;

    @Autowired
    StorageMapper storageMapper;

    @Autowired
    PermissionMapper permissionMapper;

    @Autowired
    LogMapper logMapper;

    @Autowired
    AuthorityMapper authorityMapper;

    @Autowired
    AuthorPermissionMapper authorPermissionMapper;

    @Autowired
    SystemMapper systemMapper;

    /**
     * @param adListBo
     * @author thz
     * @title
     * @description:
     * @param:
     * @return:
     */
    @Override
    public BaseData<AdminListItemVO> queryAdminInfo(AdminListBO adListBo) {
        PageHelper.startPage(adListBo.getPage(), adListBo.getLimit());

        AdminExample adminExample = new AdminExample();
        AdminExample.Criteria criteria = adminExample.createCriteria();
        if (adListBo.getUsername() != null) {
            criteria.andUsernameLike("%" + adListBo.getUsername() + "%");
        }
        adminExample.setOrderByClause(adListBo.getSort() + " " + adListBo.getOrder());
        List<AdminUsedByTHZ> admins = adminMapper.selectByExample(adminExample);

        ArrayList<AdminListItemVO> adminListItemVOS = new ArrayList<>();
        for (AdminUsedByTHZ admin : admins) {
            String[] split = admin.getRoleIds().substring(1, admin.getRoleIds().length() - 1).split(",");
            List<Integer> collect = new ArrayList<>();
            if (!"".equals(split[0])) {
                collect = Arrays.stream(split)
                        .map(s -> Integer.parseInt(s.trim()))
                        .collect(Collectors.toList());
            }
            if (!admin.getDeleted()) {
                adminListItemVOS.add(new AdminListItemVO(admin.getId(), admin.getUsername(), admin.getAvatar(), collect));
            }
        }
        PageInfo<AdminUsedByTHZ> adminPageInfo = new PageInfo<>(admins);
        int total = (int) adminPageInfo.getTotal();
        return BaseData.ok(adminListItemVOS, total);
    }

    @SneakyThrows
    @Override
    public AdminCreateVO addAdmin(AdminCreateBO adminCreateBO) {
        //// TODO: 2021/7/8
//        md5加密
//        String password = DigestUtils.md5DigestAsHex(adminCreateBO.getPassword().getBytes());
//        adminCreateBO.setPassword(password);

        AdminUsedByTHZ admin = SystemConverter.convertToAdmin(adminCreateBO);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = simpleDateFormat.parse(simpleDateFormat.format(new Date()));
        admin.setAddTime(date);
        admin.setUpdateTime(date);
        admin.setAvatar(adminCreateBO.getAvatar());

        adminMapper.insertSelective(admin);
        AdminCreateVO adminCreateVO = SystemConverter.convertToAdminCreateVO(admin);
        return adminCreateVO;
    }

    @Override
    public AdminUpdateVo changeAdmin(AdminUpdateBO adminUpdateBO) {
        AdminUsedByTHZ admin = SystemConverter.convertToAdmin(adminUpdateBO);

        adminMapper.updateByPrimaryKeySelective(admin);
        AdminUpdateVo adminUpdateVo = SystemConverter.convertToAdminUpdateVO(admin);
        return adminUpdateVo;
    }

    @Override
    public void removeAdmin(AdminDeleteBO adminDeleteBO) {
        AdminUsedByTHZ admin = SystemConverter.convertToAdmin(adminDeleteBO);

        adminMapper.updateByPrimaryKeySelective(admin);

    }

    @Override
    public List<RoleOptionsVO> queryRole() {
        RoleExample roleExample = new RoleExample();
        roleExample.setOrderByClause("id asc");
        List<Role> roles = roleMapper.selectByExample(roleExample);

        List<RoleOptionsVO> roleOptionsVOS = new ArrayList<>();

        for (Role role : roles) {
            if (!role.getDeleted()) {
                roleOptionsVOS.add(new RoleOptionsVO(role.getId(), role.getName()));
            }
        }

        return roleOptionsVOS;
    }

    @Override
    public StorageCreateVO addStorage(File newFile, MultipartFile file) {
        Storage storage = new Storage();

        String url = host + ":8083/wx/storage/fetch/" + newFile.getName();
        storage.setAddTime(new Date());
        storage.setUpdateTime(new Date());
        storage.setKey(newFile.getName());
        storage.setName(file.getOriginalFilename());
        storage.setSize((int) file.getSize());
        storage.setType(file.getContentType());
        storage.setUrl(url);
        storageMapper.insertSelective(storage);
        StorageCreateVO storageCreateVO = SystemConverter.convertToStorageCreateVO(storage);

        return storageCreateVO;
    }

    @Override
    public BaseData<RoleListItemVO> queryRoleList(RoleListBO roleListBO) {
        PageHelper.startPage(roleListBO.getPage(), roleListBO.getLimit());

        RoleExample roleExample = new RoleExample();
        RoleExample.Criteria criteria = roleExample.createCriteria();
        if (roleListBO.getName() != null) {
            criteria.andNameLike("%" + roleListBO.getName() + "%");
        }
        roleExample.setOrderByClause(roleListBO.getSort() + " " + roleListBO.getOrder());
        List<Role> roles = roleMapper.selectByExample(roleExample);


        ArrayList<RoleListItemVO> roleListItemVOS = new ArrayList<>();
        for (Role role : roles) {
            if (!role.getDeleted()) {
                roleListItemVOS.add(new RoleListItemVO(role.getId(), role.getName(), role.getDesc(), role.getEnabled(), role.getAddTime(), role.getUpdateTime(),
                        role.getDeleted()));
            }
        }
        PageInfo<Role> rolePageInfo = new PageInfo<>(roles);
        int total = (int) rolePageInfo.getTotal();
        return BaseData.ok(roleListItemVOS, total);
    }

    @Override
    public RoleCreateVO createRole(RoleCreateBO roleCreateBO) {
        Role role = SystemConverter.convertToRole(roleCreateBO);
        roleMapper.insertSelective(role);
        RoleCreateVO roleCreateVO = SystemConverter.convertToRoleCreateVO(role);
        return roleCreateVO;
    }

    @Override
    public void removeRole(RoleDeleteBO roleDeleteBO) {
        Role role = SystemConverter.convertToRole(roleDeleteBO);
        roleMapper.updateByPrimaryKeySelective(role);

        PermissionExample permissionExample = new PermissionExample();
        permissionExample.createCriteria().andRoleIdEqualTo(roleDeleteBO.getId());
        Permission permission = new Permission(null, null, null, new Date(), new Date(), true);
        permissionMapper.updateByExampleSelective(permission, permissionExample);


    }

    @Override
    public void changeRole(RoleUpdateBO roleUpdateBO) {
        Role role = SystemConverter.convertToRole(roleUpdateBO);
        roleMapper.updateByPrimaryKeySelective(role);
    }

    @Override
    public RolePermissionVO queryRolePermission(Integer roleId) {
        PermissionExample permissionExample = new PermissionExample();
        PermissionExample.Criteria criteria = permissionExample.createCriteria();
        if (roleId != null) {
            criteria.andRoleIdEqualTo(roleId);
        }
        //管理员拥有的权限
        List<Permission> owePermissions = permissionMapper.selectByExample(permissionExample);
        ArrayList<String> owePermissionList = new ArrayList<>();
        if (owePermissions.size() != 0) {
            if (!"*".equals(owePermissions.get(0).getPermission())) {
                for (Permission permission : owePermissions) {
                    owePermissionList.add(permission.getPermission());
                }
            } else {
                AuthorPermissionExample authorPermissionExample = new AuthorPermissionExample();
                List<AuthorPermission> authorPermissions = authorPermissionMapper.selectByExample(authorPermissionExample);
                for (AuthorPermission authorPermission : authorPermissions) {
                    owePermissionList.add(authorPermission.getPermission());
                }
            }
        }

        AuthorityExample firstLevelAuthorityExample = new AuthorityExample();
        AuthorityExample.Criteria firstLevelAuthorityExampleCriteria = firstLevelAuthorityExample.createCriteria();
        firstLevelAuthorityExampleCriteria.andPidEqualTo(0);
        //一级列表
        List<Authority> firstLevelAuthors = authorityMapper.selectByExample(firstLevelAuthorityExample);

        ArrayList<RolePermissionVO.SystemPermissionsBean> systemPermissionsBeans = new ArrayList<>();
        for (Authority firstLevelAuthor : firstLevelAuthors) {
            AuthorityExample secondLevelAuthorityExample = new AuthorityExample();
            AuthorityExample.Criteria secondLevelAuthorityExampleCriteria = secondLevelAuthorityExample.createCriteria();
            secondLevelAuthorityExampleCriteria.andPidEqualTo(firstLevelAuthor.getId());
            //二级列表
            List<Authority> secondLevelAuthors = authorityMapper.selectByExample(secondLevelAuthorityExample);

            ArrayList<RolePermissionVO.SystemPermissionsBean.ChildrenBeanX> childrenBeanXES = new ArrayList<>();
            for (Authority secondLevelAuthor : secondLevelAuthors) {
                AuthorPermissionExample authorPermissionExample = new AuthorPermissionExample();
                AuthorPermissionExample.Criteria authorPermissionExampleCriteria = authorPermissionExample.createCriteria();
                authorPermissionExampleCriteria.andAutoIdEqualTo(secondLevelAuthor.getId());
                //二级列表拥有的权限
                List<AuthorPermission> authorPermissions = authorPermissionMapper.selectByExample(authorPermissionExample);
                ArrayList<RolePermissionVO.SystemPermissionsBean.ChildrenBeanX.ChildrenBean> childrenBeans = new ArrayList<>();
                for (AuthorPermission authorPermission : authorPermissions) {
                    childrenBeans.add(new RolePermissionVO.SystemPermissionsBean.ChildrenBeanX.ChildrenBean(authorPermission.getPermission(),
                            authorPermission.getLabel(), authorPermission.getApi()));
                }

                childrenBeanXES.add(new RolePermissionVO.SystemPermissionsBean.ChildrenBeanX(secondLevelAuthor.getName(),
                        secondLevelAuthor.getLabel(), childrenBeans));
            }

            systemPermissionsBeans.add(new RolePermissionVO.SystemPermissionsBean(firstLevelAuthor.getName(),
                    firstLevelAuthor.getLabel(), childrenBeanXES));
        }


//        for (RolePermissionVO.SystemPermissionsBean systemPermissionsBean : systemPermissionsBeans) {
//            Authority firstLevelAuthor = firstLevelAuthors.remove(0);
//            systemPermissionsBean.setId(firstLevelAuthor.getName());
//            systemPermissionsBean.setLabel(firstLevelAuthor.getLabel());
//            ArrayList<RolePermissionVO.SystemPermissionsBean.ChildrenBeanX> childrenBeanXES = new ArrayList<>();
//            systemPermissionsBean.setChildren(childrenBeanXES);
//
//            AuthorityExample secondLevelAuthorityExample = new AuthorityExample();
//            AuthorityExample.Criteria secondLevelAuthorityExampleCriteria = secondLevelAuthorityExample.createCriteria();
//            secondLevelAuthorityExampleCriteria.andPidEqualTo(firstLevelAuthor.getId());
//            //二级权限列表
//            List<Authority> secondLevelAuthors = authorityMapper.selectByExample(secondLevelAuthorityExample);
//            for (RolePermissionVO.SystemPermissionsBean.ChildrenBeanX childrenBeanX : childrenBeanXES) {
//                Authority secondLevelAuthor = secondLevelAuthors.remove(0);
//                childrenBeanX.setId(secondLevelAuthor.getName());
//                childrenBeanX.setLabel(secondLevelAuthor.getLabel());
//                ArrayList<RolePermissionVO.SystemPermissionsBean.ChildrenBeanX.ChildrenBean> childrenBeans = new ArrayList<>();
//                childrenBeanX.setChildren(childrenBeans);
//
//                AuthorPermissionExample authorPermissionExample = new AuthorPermissionExample();
//                AuthorPermissionExample.Criteria authorPermissionExampleCriteria = authorPermissionExample.createCriteria();
//                authorPermissionExampleCriteria.andAutoIdEqualTo(secondLevelAuthor.getId());
//                //二级权限列表拥有的权限
//                List<AuthorPermission> authorPermissions = authorPermissionMapper.selectByExample(authorPermissionExample);
//                for (RolePermissionVO.SystemPermissionsBean.ChildrenBeanX.ChildrenBean childrenBean : childrenBeans) {
//                    AuthorPermission authorPermission = authorPermissions.remove(0);
//                    childrenBean.setLabel(authorPermission.getLabel());
//                    childrenBean.setId(authorPermission.getPermission());
//                    childrenBean.setApi(authorPermission.getApi());
//                }
//
//
//            }
//
//
//        }

        return RolePermissionVO.ok(owePermissionList, systemPermissionsBeans);
    }

    @Override
    public BaseData<StorageListItemVO> queryStorage(StorageListBO storageListBO) {
        PageHelper.startPage(storageListBO.getPage(), storageListBO.getLimit());

        StorageExample storageExample = new StorageExample();
        StorageExample.Criteria criteria = storageExample.createCriteria();
        if (storageListBO.getName() != null && !"".equals(storageListBO.getName().trim())) {
            criteria.andNameLike("%" + storageListBO.getName() + "%");
        }
        if (storageListBO.getKey() != null && !"".equals(storageListBO.getKey().trim())) {
            criteria.andKeyLike("%" + storageListBO.getKey() + "%");
        }
        storageExample.setOrderByClause(storageListBO.getSort() + " " + storageListBO.getOrder());
        List<Storage> storages = storageMapper.selectByExample(storageExample);
//        List<Storage> storages = storageMapper.selectByKeyAndName(storageListBO);

        ArrayList<StorageListItemVO> storageListItemVOS = new ArrayList<>();
        for (Storage storage : storages) {
            if (!storage.getDeleted()) {
                storageListItemVOS.add(new StorageListItemVO(storage.getId(), storage.getKey(), storage.getName(), storage.getType(),
                        storage.getSize(), storage.getUrl(), storage.getAddTime(), storage.getUpdateTime(), storage.getDeleted()));
            }
        }
        PageInfo<Storage> storagePageInfo = new PageInfo<>(storages);
        int total = (int) storagePageInfo.getTotal();
        return BaseData.ok(storageListItemVOS, total);
    }

    @Override
    public StorageUpdateVO changeStorage(StorageUpdateBo storageUpdateBo) {
        Storage storage = SystemConverter.convertToStorage(storageUpdateBo);
        storageMapper.updateByPrimaryKeySelective(storage);
        StorageUpdateVO storageUpdateVO = SystemConverter.convertToStorageUpdateVO(storage);
        return storageUpdateVO;
    }

    @Override
    public void removeStorage(StorageDeleteBO storageDeleteBO) {
        Storage storage = SystemConverter.convertToStorage(storageDeleteBO);
        storageMapper.updateByPrimaryKeySelective(storage);
    }

    @Override
    public BaseData<LogListItemVO> queryLog(LogListBO logListBO) {
        PageHelper.startPage(logListBO.getPage(), logListBO.getLimit());

        LogExample logExample = new LogExample();
        LogExample.Criteria criteria = logExample.createCriteria();
        if (logListBO.getName() != null) {
            criteria.andAdminLike("%" + logListBO.getName() + "%");
        }

        logExample.setOrderByClause(logListBO.getSort() + " " + logListBO.getOrder());
        List<Log> logs = logMapper.selectByExample(logExample);

        ArrayList<LogListItemVO> logListItemVOS = new ArrayList<>();
        for (Log log : logs) {
            if (!log.getDeleted()) {
                logListItemVOS.add(new LogListItemVO(log.getId(), log.getAdmin(), log.getIp(), log.getType(), log.getAction(),
                        log.getStatus(), log.getResult(), log.getComment(), log.getAddTime(), log.getUpdateTime(), log.getDeleted()));
            }
        }
        PageInfo<Log> logPageInfo = new PageInfo<>(logs);
        int total = (int) logPageInfo.getTotal();
        return BaseData.ok(logListItemVOS, total);
    }

    @Override
    public void changeRolePermission(RolePermissionPostBO rolePermissionPostBO) {
        PermissionExample permissionExample = new PermissionExample();
        permissionExample.createCriteria().andRoleIdEqualTo(rolePermissionPostBO.getRoleId());
        permissionMapper.deleteByExample(permissionExample);

        List<Permission> permissions = SystemConverter.convertToPermissionList(rolePermissionPostBO);
        for (Permission permission : permissions) {
            permissionMapper.insertSelective(permission);
        }
    }

    @Override
    public System querySystemByKeyName(String keyName) {
        SystemExample systemExample = new SystemExample();
        systemExample.createCriteria().andKeyNameEqualTo(keyName).andDeletedEqualTo(false);

        List<System> systems = systemMapper.selectByExample(systemExample);
        if (systems.size() != 0) {
            return systems.get(0);
        }
        return null;

    }
}
